package com.ruoyi.api.v1;

import cn.hutool.core.date.DateUtil;
import com.ruoyi.cinema.BO.*;
import com.ruoyi.cinema.DTO.AreaPromoYzDTO;
import com.ruoyi.cinema.DTO.LockSeatRetDTO;
import com.ruoyi.cinema.DTO.SchedulePromoYzDTO;
import com.ruoyi.cinema.domain.*;
import com.ruoyi.cinema.mapper.FilmScheduleMapper;
import com.ruoyi.cinema.service.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.utils.YzResult;
import com.ruoyi.utils.YzUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController("v1_FilmSchedule")
@RequestMapping(value = "api/v1/filmSchedule")
public class FilmScheduleController extends BaseController {
    @Autowired
    private IFilmScheduleService filmScheduleService;
    @Autowired
    private FilmScheduleMapper filmScheduleMapper;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private IScheduleAreaInfoService scheduleAreaInfoService;
    @Autowired
    private IFilmService filmService;
    @Autowired
    private ICinemaService cinemaService;


    @GetMapping("/list")
    public TableDataInfo list(FilmScheduleBO filmScheduleBO) {
        if(null == filmScheduleBO.getShowDate()){
            return getDataTableError(-1,"showDate 不能为空");
        }
        if(null == filmScheduleBO.getCustomerId()){
            return getDataTableError(-1 ,"cusotmerId 不能为空");
        }
        Customer customer = customerService.selectCustomerById(filmScheduleBO.getCustomerId());
        if(null == customer){
            return getDataTableError(-1,"找不到相应的customer");
        }
        if(!StringUtils.isEmpty(customer.getPhone())){
            String accessToken = customerService.getAccessToken(customer.getId(),customer.getPhone());
            filmScheduleBO.setAccessToken(accessToken);
        }
        if(null == filmScheduleBO.getCinemaId()){
            return getDataTableError(-1 ,"cinemaId 不能为空");
        }
        Cinema cinema = cinemaService.selectCinemaById(filmScheduleBO.getCinemaId());
        filmScheduleBO.setCinemaLinkId(cinema.getCinemaLinkId());
        startPage();
        //todo 还没有做校验
        if(null != filmScheduleBO.getShowDate()){
            filmScheduleBO.setBeginShowDateTime(DateUtil.beginOfDay(filmScheduleBO.getShowDate()).toJdkDate());
            Long currentTime = System.currentTimeMillis();
            if(filmScheduleBO.getBeginShowDateTime().getTime() < currentTime){
                filmScheduleBO.setBeginShowDateTime(new Date(currentTime));
            }
            filmScheduleBO.setEndShowDateTime(DateUtil.endOfDay(filmScheduleBO.getShowDate()).toJdkDate());
        }

        List<FilmSchedule> list = filmScheduleService.selectFilmScheduleForApi(filmScheduleBO);
        return getDataTable(list);
    }

    @GetMapping("/getScheduleAreaPrice")
    public AjaxResult getScheduleAreaPrice(LockSeatBO lockSeatBO){
        if(null == lockSeatBO.getId()){
            return AjaxResult.error(-1,"scheduleId 不能为空");
        }
        if(null == lockSeatBO.getCustomerId()){
            return AjaxResult.error(-1,"customerId 不能为空");
        }
        FilmSchedule fs = filmScheduleService.selectFilmScheduleById(lockSeatBO.getId());
        if(null ==fs){
            return AjaxResult.error(-1,"未找到对应的排期");
        }
        ScheduleAreaInfo scheduleAreaInfo = new ScheduleAreaInfo();
        scheduleAreaInfo.setScheduleId(fs.getId());
        List<ScheduleAreaInfo> scheduleAreaInfoList= scheduleAreaInfoService.selectScheduleAreaInfoList(scheduleAreaInfo);
        for (ScheduleAreaInfo sai :scheduleAreaInfoList) {
            sai.setTicketFee(fs.getTicketFee());
            sai.setFeeType(fs.getFeeType());
        }
        SchedulePriceBO schedulePriceBO = new SchedulePriceBO();
        schedulePriceBO.setScheduleAreaInfoList(scheduleAreaInfoList);
        Customer customer = customerService.selectCustomerById(lockSeatBO.getCustomerId());
        if(null == customer){
            return AjaxResult.error(-1,"未找到对应的用户");
        }
        if(StringUtils.isEmpty(customer.getPhone())){
            return AjaxResult.error(-1,"用户未绑定手机号，请先绑定");
        }
        String accessToken = customerService.getAccessToken(customer.getId(),customer.getPhone());
        YzResult<SchedulePromoYzDTO> schedulePromoYzDTOResult = YzUtils.getSeatMapPromoList(accessToken,fs.getCinemaLinkId(),fs.getScheduleId());
        if(schedulePromoYzDTOResult.getResultCode().equals(Constants.YZSUCCESS) && schedulePromoYzDTOResult.getData().getBizCode().equals(Constants.BIZSUCCESS)){
            SchedulePromoYzDTO  schedulePromoYzDTO = schedulePromoYzDTOResult.getData().getBizData();
            // 这里做了一下排序，让这个价格顺序和原始价格顺序相同
            if(null != schedulePromoYzDTO && null !=schedulePromoYzDTO.getAreaPromoList() && !schedulePromoYzDTO.getAreaPromoList().isEmpty()){
                List<AreaPromoYzDTO> areaPromoList = new ArrayList<>(schedulePromoYzDTO.getAreaPromoList().size());
                for (ScheduleAreaInfo sai :schedulePriceBO.getScheduleAreaInfoList()) {
                    for (AreaPromoYzDTO apy :schedulePromoYzDTO.getAreaPromoList()) {
                        if(sai.getAreaId().equals(apy.getAreaId())){
                            areaPromoList.add(apy);
                        }
                    }
                }
                schedulePromoYzDTO.setAreaPromoList(areaPromoList);
            }
            schedulePriceBO.setSchedulePromo(schedulePromoYzDTO);
        }

        return AjaxResult.success(schedulePriceBO);
    }

    @GetMapping("/scheduleDate")
    public AjaxResult getScheduleDate(FilmSchedule filmSchedule){
        filmSchedule.setSaleStatus("Y");
        List<String> dateList = filmScheduleMapper.findDateList(filmSchedule);
        return AjaxResult.success(dateList);
    }

    @GetMapping("/getScheduleHallSeat")
    private AjaxResult getScheduleHallSeat(FilmSchedule filmSchedule){
        if(null == filmSchedule.getId()){
            return AjaxResult.error(-1,"scheduleId 不能为空");
        }
       FilmSchedule fs =  filmScheduleService.selectFilmScheduleById(filmSchedule.getId());
        if(null == fs){
            return AjaxResult.error(-1,"找不到对应的排期");
        }
        return AjaxResult.success(filmScheduleService.getScheduleHallSeat(fs));
    }

    @PostMapping("/lockSeat")
    private AjaxResult lockSeat(@RequestBody LockSeatBO lockSeatBO){
        if(null == lockSeatBO.getId()){
            return AjaxResult.error(-1 ,"ScheduleId不能为空");
        }
        FilmSchedule filmSchedule = filmScheduleService.selectFilmScheduleById(lockSeatBO.getId());
        if(null == filmSchedule){
            return AjaxResult.error(-1, "找不到对应的排期");
        }
        if(null == lockSeatBO.getSeatCodeList() || lockSeatBO.getSeatCodeList().isEmpty()){
            return AjaxResult.error(-1,"座位列表不能为空");
        }
        if(null == lockSeatBO.getCustomerId()){
            return AjaxResult.error(-1,"customerId不能为空");
        }
        Customer customer =  customerService.selectCustomerById(lockSeatBO.getCustomerId());
        if(null == customer){
            return AjaxResult.error(-1,"找不到对应的customer");
        }
        String accessToken = customerService.getAccessToken(customer.getId(),customer.getPhone());
        if(StringUtils.isEmpty(accessToken)){
            return AjaxResult.error(-1,"获取accessToken失败");
        }
        lockSeatBO.setOutId(IdUtils.fastSimpleUUID());
        lockSeatBO.setScheduleId(filmSchedule.getScheduleId());
        lockSeatBO.setScheduleKey(filmSchedule.getScheduleKey());
        lockSeatBO.setCinemaLinkId(filmSchedule.getCinemaLinkId());
        List<String> seatList = lockSeatBO.getSeatCodeList().stream().map(SeatAndAreaBO::getSeatCode).collect(Collectors.toList());
        YzResult<LockSeatRetDTO> lockSeatRetDTOResult = YzUtils.lockSeat(filmSchedule.getCinemaLinkId(),filmSchedule.getScheduleId(),filmSchedule.getScheduleKey(),lockSeatBO.getOutId() ,seatList,accessToken);
        if(lockSeatRetDTOResult.getResultCode().equals(Constants.YZSUCCESS) && lockSeatRetDTOResult.getData().getBizCode().equals(Constants.BIZSUCCESS)){
            LockSeatRetDTO lsrd = lockSeatRetDTOResult.getData().getBizData();
            if(null !=lsrd){
                Date date = lsrd.getExpireTime();
                System.out.println(" expire Time " + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",date));
                lockSeatBO.setLockOrderId(lsrd.getLockOrderId());
                lockSeatBO.setExpireTime(date);
                Long secondLeft = ((date.getTime() - System.currentTimeMillis())/ 1000) - 10;
                redisCache.setCacheObject(lockSeatBO.getLockOrderId()+Constants.LOCK_SEAT_KEY,lockSeatBO,secondLeft, TimeUnit.SECONDS);
                return AjaxResult.success(lockSeatBO);
            }
        }
        return AjaxResult.error(-1,"锁坐失败");
    }

    @PostMapping("/unLockSeat")
    private AjaxResult unLockSeat(@RequestBody LockSeatBO lockSeatBO){
        if(StringUtils.isEmpty(lockSeatBO.getLockOrderId())){
            return AjaxResult.error(-1,"lockOrderId 不能为空");
        }
        LockSeatBO ls = redisCache.getCacheObject(lockSeatBO.getLockOrderId()+Constants.LOCK_SEAT_KEY);
        if(null == ls){
            return  AjaxResult.error(-1,"找不到对应的已锁定的座位");
        }else {
            Customer customer = customerService.selectCustomerById(ls.getCustomerId());
            String accessToken = customerService.getAccessToken(customer.getId(),customer.getPhone());
            if(StringUtils.isEmpty(accessToken)){
                return AjaxResult.error(-1,"获取accessToken失败");
            }
            YzResult<String> stringYzResult = YzUtils.unlockSeat(ls.getCinemaLinkId(),ls.getLockOrderId(),accessToken);
            if(stringYzResult.getResultCode().equals(Constants.YZSUCCESS) && stringYzResult.getData().getBizCode().equals(Constants.BIZSUCCESS)){
                redisCache.deleteObject(lockSeatBO.getLockOrderId()+Constants.LOCK_SEAT_KEY);
                return AjaxResult.success();
            }
        }

        return AjaxResult.error(-1,"解锁失败");

    }

    @GetMapping("/getLockedScheduleInfo")
    public AjaxResult getLockedScheduleInfo(LockSeatBO lockSeatBO){
        if(StringUtils.isEmpty(lockSeatBO.getLockOrderId())){
            return AjaxResult.error(-1,"lockOrderId 不能为空");
        }
        LockSeatBO ls = redisCache.getCacheObject(lockSeatBO.getLockOrderId()+Constants.LOCK_SEAT_KEY);
        if(null == ls){
            return AjaxResult.error(-1,"找不到对应的锁坐信息");
        }

        FilmSchedule fs = filmScheduleService.selectFilmScheduleById(ls.getId());
        Film film =  filmService.selectFilmById(fs.getFilmId());
        fs.setFilm(film);
        return AjaxResult.success(fs);
    }

    @PostMapping("/getEffectivePromoList")
    public AjaxResult getEffectivePromoList(@RequestBody GetEffectivePromoBO gepb){
        if(StringUtils.isEmpty(gepb.getCustomerId())){
            return AjaxResult.error(-1,"customerId 不能为空");
        }
        Customer customer = customerService.getById(gepb.getCustomerId());
        String accessToken = customerService.getAccessToken(customer.getId(),customer.getPhone());


        if(StringUtils.isEmpty(gepb.getLockOrderId())){
            return AjaxResult.error(-1,"lockOrderId不能为空");
        }
        LockSeatBO ls = redisCache.getCacheObject(gepb.getLockOrderId()+Constants.LOCK_SEAT_KEY);
        if(null == ls){
            return AjaxResult.error(-1,"找不到对应的锁坐信息");
        }

        gepb.setAccessToken(accessToken);
        gepb.setCustomer(customer);
        List<CanUsePriceBO>  canUsePriceBOList = filmScheduleService.getCanUsePrice(gepb,ls);
        if(null != canUsePriceBOList && !canUsePriceBOList.isEmpty()){
            ls.setCanUsePriceBOList(canUsePriceBOList);
            Long leftSecond = redisCache.getCacheObjectExpire(gepb.getLockOrderId()+Constants.LOCK_SEAT_KEY);
            redisCache.setCacheObject(gepb.getLockOrderId()+Constants.LOCK_SEAT_KEY,ls,leftSecond,TimeUnit.SECONDS);
            return AjaxResult.success(canUsePriceBOList);
        }
        return AjaxResult.error(-1,"获取失败");
    }

    @GetMapping("/getSeatMapPromoList")
    public AjaxResult getSeatMapPromoList(LockSeatBO lockSeatBO){
        if(null == lockSeatBO.getId()){
            return AjaxResult.error(-1, "scheduleId 不能为空");
        }
        FilmSchedule fs = filmScheduleService.selectFilmScheduleById(lockSeatBO.getId());
        Customer customer = customerService.selectCustomerById(lockSeatBO.getCustomerId());
        String accessToken = customerService.getAccessToken(customer.getId(),customer.getPhone());
        YzResult<SchedulePromoYzDTO> schedulePromoYzDTOResult = YzUtils.getSeatMapPromoList(accessToken,fs.getCinemaLinkId(),fs.getScheduleId());
        if(schedulePromoYzDTOResult.getResultCode().equals(Constants.YZSUCCESS) && schedulePromoYzDTOResult.getData().getBizCode().equals(Constants.BIZSUCCESS)){
            SchedulePromoYzDTO  schedulePromoYzDTO = schedulePromoYzDTOResult.getData().getBizData();
            return AjaxResult.success(schedulePromoYzDTO);
        }
        return AjaxResult.error(-1,"获取失败");

    }


}
